﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using KWR.DAL;

namespace AffineTransformation
{
    public partial class Main : Form
    {
        string kwrName = string.Empty;
        string chaosName = string.Empty;

        Bitmap orginal;

        public Main()
        {
            InitializeComponent();
        }

        public bool ThumbnailCallback()
        {
            return false;
        }

        private void wybórKWRToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.ShowDialog();

            if (!string.IsNullOrEmpty(dlg.FileName))
            {
                Bitmap b = new Bitmap(dlg.FileName);

                Image.GetThumbnailImageAbort myCallback = new Image.GetThumbnailImageAbort(ThumbnailCallback);

                picImage.Width = Convert.ToInt32(Convert.ToDecimal(b.Width) * Convert.ToDecimal(picImage.Height) / Convert.ToDecimal(b.Height));
                picImage.Height = Convert.ToInt32(Convert.ToDecimal(b.Height) * Convert.ToDecimal(picImage.Height) / Convert.ToDecimal(b.Height));

                picImage.Top = (this.Size.Height - picImage.Height) / 2;
                picImage.Left = (this.Size.Width - picImage.Width) / 2;

                picImage.Image = b.GetThumbnailImage(picImage.Width, picImage.Height, null, IntPtr.Zero);

                orginal = (Bitmap)picImage.Image.Clone();
            }
        }

        private void Main_Load(object sender, EventArgs e)
        {
            DataTable dt = DataAccess.GetKwrs();

            foreach (DataRow item in dt.Rows)
            {
                cbKWR.Items.Add(item["name"]);
            }
        }

        private void cbKWR_SelectedIndexChanged(object sender, EventArgs e)
        {
            ToolStripComboBox cb = (ToolStripComboBox)sender;
            kwrName = cb.SelectedItem.ToString();
        }

        private void iteracjeKWRToolStripMenuItem_Click(object sender, EventArgs ea)
        {
            Bitmap oldB = orginal;
            Bitmap newB = new Bitmap(picImage.Width, picImage.Height);

            DataTable dt = DataAccess.GetTransformations(kwrName);

            this.Cursor = Cursors.WaitCursor;

            foreach (DataRow item in dt.Rows)
            {
                double a = Convert.ToDouble(item["a"]);
                double b = Convert.ToDouble(item["b"]);
                double c = Convert.ToDouble(item["c"]);
                double d = Convert.ToDouble(item["d"]);
                double e = Convert.ToDouble(item["e"]);
                double f = Convert.ToDouble(item["f"]);

                for (int i = 0; i < oldB.Width; i++)
                {
                    for (int j = 0; j < oldB.Height; j++)
                    {
                        Color pc = oldB.GetPixel(i,j);

                        double oldX = Convert.ToDouble(i) / Convert.ToDouble(oldB.Width);
                        double oldY = Convert.ToDouble(j) / Convert.ToDouble(oldB.Height);

                        int x = Convert.ToInt32(Convert.ToDouble(a * oldX + b * oldY + e) * Convert.ToDouble(oldB.Width));
                        int y = Convert.ToInt32(Convert.ToDouble(c * oldX + d * oldY + f) * Convert.ToDouble(oldB.Height));

                        if (x >= 0 && y >= 0 && x < oldB.Width && y < oldB.Height)
                        {
                            newB.SetPixel(x, y, pc);
                        }
                    }
                 }
            }

            picImage.Image = (Bitmap)newB.Clone();

            orginal = newB;

            //picImage.Image.RotateFlip(RotateFlipType.Rotate180FlipX);

            this.Cursor = Cursors.Arrow;
        }

        private double[] m_Prob = new double[4];
        private double[, ,] m_Func = new double[4, 2, 2];
        private double[,] m_Plus = new double[4, 2];
        private Color[] m_Clr = new Color[4];

        private void paprotkaBarnsleyaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_Clr[0] = Color.Red;
            m_Prob[0] = 0.01;
            m_Func[0, 0, 0] = 0;
            m_Func[0, 0, 1] = 0;
            m_Func[0, 1, 0] = 0;
            m_Func[0, 1, 1] = 0.16;
            m_Plus[0, 0] = 0;
            m_Plus[0, 1] = 0;

            m_Clr[1] = Color.Green;
            m_Prob[1] = 0.85;
            m_Func[1, 0, 0] = 0.85;
            m_Func[1, 0, 1] = 0.04;
            m_Func[1, 1, 0] = -0.04;
            m_Func[1, 1, 1] = 0.85;
            m_Plus[1, 0] = 0;
            m_Plus[1, 1] = 1.6;

            m_Clr[2] = Color.Blue;
            m_Prob[2] = 0.08;
            m_Func[2, 0, 0] = 0.2;
            m_Func[2, 0, 1] = -0.26;
            m_Func[2, 0, 1] = -0.23;
            m_Func[2, 1, 1] = 0.22;
            m_Plus[2, 0] = 0;
            m_Plus[2, 1] = 1.6;

            m_Clr[3] = Color.White;
            m_Prob[3] = 0.06;
            m_Func[3, 0, 0] = -0.15;
            m_Func[3, 0, 1] = 0.28;
            m_Func[3, 1, 0] = 0.26;
            m_Func[3, 1, 1] = 0.24;
            m_Plus[3, 0] = 0;
            m_Plus[3, 1] = 0.44;

            // New colors to make a lime fern.
            m_Clr[0] = Color.Black;
            m_Clr[1] = Color.Black;
            m_Clr[2] = Color.Black;
            m_Clr[3] = Color.Black;

            MakeFern();
        }

        private void MakeFern()
        {
            Bitmap bm = new Bitmap(picImage.Width, picImage.Height);
            using (Graphics gr = Graphics.FromImage(bm))
            {
                gr.Clear(picImage.BackColor);

                Random rnd = new Random();
                Color clr = Color.Red;
                int func_num = 0, ix, iy;
                double x = 1, y = 1, x1, y1;
                for (int i = 1; i <= 100000; i++)
                {
                    double num = rnd.NextDouble();
                    for (int j = 0; j <= 3; j++)
                    {
                        num = num - m_Prob[j];
                        if (num <= 0)
                        {
                            func_num = j;
                            clr = m_Clr[j];
                            break;
                        }
                    }

                    x1 = x * m_Func[func_num, 0, 0] + y * m_Func[func_num, 0, 1] + m_Plus[func_num, 0];
                    y1 = x * m_Func[func_num, 1, 0] + y * m_Func[func_num, 1, 1] + m_Plus[func_num, 1];
                    x = x1;
                    y = y1;

                    const double W_XMIN = -4;
                    const double W_XMAX = 4;
                    const double W_YMIN = -0.1f;
                    const double W_YMAX = 10.1f;
                    const double W_WID = W_XMAX - W_XMIN;
                    const double W_HGT = W_YMAX - W_YMIN;
                    ix = (int)Math.Round((x - W_XMIN) / W_WID * picImage.Width);
                    iy = (int)Math.Round((picImage.Height - 1) - (y - W_YMIN) / W_HGT * picImage.Height);
                    if ((ix >= 0) && (iy >= 0)
                        && (ix < picImage.Width)
                        && (iy < picImage.Height))
                    {
                        bm.SetPixel(ix, iy, clr);
                    }
                }
            }

            // Display the result.
            picImage.Image = bm;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            iteracjeKWRToolStripMenuItem_Click(sender, e);
        }
  
    }
}
